﻿Public Class CCipher
    Private intDataKey As Long      '编码钥匙
    Private strData As String    '未编码数据
    Private strFile As String    '已编码数据

    ''' <summary>
    ''' 根据给定数值（0-65535)，返回编码后得到的字符串（4位）
    ''' </summary>
    ''' <param name="val"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function DataConvert_NumToChr(val As Long) As String
        Dim i As Integer
        Dim ch As Long
        Dim str As String

        str = ""
        If val < 0 Then val = val + 65536

        val = val - intDataKey
        If val < 0 Then val = val + 65536

        intDataKey = (val * 7) Mod 65536

        For i = 1 To 4
            ch = val Mod 16
            If ch > 9 Then ch = ch + 7
            ch = ch + 48
            str = Chr(ch) & str
            val = val \ 16
        Next i

        DataConvert_NumToChr = str
    End Function


    ''' <summary>
    ''' 根据给定字符串（4位），返回解码后得到的数值（0-65535)
    ''' </summary>
    ''' <param name="str"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function DataConvert_ChrToNum(str As String) As String
        Dim i As Integer
        Dim ch, val As Integer
        Dim intTempDataKey As Integer

        If Len(str) <> 4 Then
            Return "?"
        End If

        val = 0

        For i = 1 To 4
            ch = Asc(Mid(str, i, 1))
            If ch > 57 Then ch = ch - 7
            ch = ch - 48
            val = val * 16 + ch
        Next i

        intTempDataKey = (val * 7) Mod 65536
        val = val + intDataKey
        If val > 65536 Then val = val - 65536

        intDataKey = intTempDataKey

        DataConvert_ChrToNum = Chr(val)
    End Function

    ''' <summary>
    ''' 编码数据和未编码数据之间的转换
    ''' </summary>
    ''' <param name="flag">true->未编码数据到编码数据  false->编码数据到未编码数据</param>
    ''' <remarks></remarks>
    Sub DataConvert(flag As Boolean)
        Dim i As Long
        Dim ch As Long
        Dim strHex As String
        Dim lngData, lngFile As Long

        intDataKey = 30000
        If flag Then    '转成存盘数据
            strFile = ""

            lngData = Len(strData)

            For i = 1 To lngData
                ch = Asc(Mid(strData, i, 1))
                strFile = strFile & DataConvert_NumToChr(ch)
            Next i
        Else            '转成实际数据
            strData = ""

            lngFile = Len(strFile) \ 4

            For i = 1 To lngFile
                strHex = Mid(strFile, i * 4 - 3, 4)
                strData = strData & DataConvert_ChrToNum(strHex)
            Next i
        End If
    End Sub

    ''' <summary>
    ''' 外部调用：加密、解密（String --> String）
    ''' </summary>
    ''' <param name="originStr"></param>
    ''' <param name="isCompress"> true-> 加密  false-> 解密</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function token_DataCompress(originStr As String, isCompress As Boolean) As String
        If Len(originStr) = 0 Then
            token_DataCompress = ""
            Exit Function
        End If
        If isCompress Then
            strData = originStr
            DataConvert(isCompress)
            token_DataCompress = strFile
        Else
            strFile = originStr
            DataConvert(isCompress)
            token_DataCompress = strData
        End If
    End Function

End Class
